package com.athenaeum.datastore.repository.impl;

import java.util.Iterator;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.athenaeum.datastore.criteria.MailCriteria;
import com.athenaeum.datastore.domain.Mail;
import com.athenaeum.datastore.helper.RepositoryPageHelper;
import com.athenaeum.datastore.repository.MailRepository;
import com.athenaeum.datastore.repository.MailRepositoryInternal;

public class MailRepositoryImpl implements MailRepositoryInternal {
	
	@PersistenceContext(type=PersistenceContextType.EXTENDED)
	private EntityManager em;

	@Override
	public Page<Mail> getByCriteria(final MailCriteria mailCriteria, final Pageable pageable) {
		Session session = (Session) em.getDelegate();
		Criteria criteria = session.createCriteria(Mail.class);
		if(ArrayUtils.isNotEmpty(mailCriteria.getIds())) {
			criteria.add(Restrictions.in("id", mailCriteria.getIds()));
		}
		if(ArrayUtils.isNotEmpty(mailCriteria.getExcludeIds())) {
			criteria.add(Restrictions.not(Restrictions.in("id", mailCriteria.getExcludeIds())));
		}
		if(ArrayUtils.isNotEmpty(mailCriteria.getMailType())) {
			criteria.add(Restrictions.in("mailType", mailCriteria.getMailType()));
		}
		if(StringUtils.isEmpty(mailCriteria.getEmail()) && ArrayUtils.isNotEmpty(mailCriteria.getRecipientTypes())) {
			criteria.createAlias("mailRecipients", "recipient");
			criteria.add(Restrictions.eq("recipient.email", mailCriteria.getEmail()));
			criteria.add(Restrictions.in("recipient.recipientType", mailCriteria.getRecipientTypes()));
		}
		if(StringUtils.isNotEmpty(mailCriteria.getSubject())) {
			criteria.add(Restrictions.ilike("subject", mailCriteria.getSubject()));
		}
		if(StringUtils.isNotEmpty(mailCriteria.getMailContent())) {
			criteria.add(Restrictions.ilike("message", mailCriteria.getMailContent()));
		}
		Sort sort = pageable.getSort();
		
		if(sort != null) {
			Iterator<org.springframework.data.domain.Sort.Order> iterator = sort.iterator();
			while(iterator.hasNext()) {
				org.springframework.data.domain.Sort.Order order = iterator.next();
				switch(order.getDirection()) {
				case ASC:
					criteria.addOrder(Order.asc(order.getProperty()));
					break;
				case DESC:
					criteria.addOrder(Order.desc(order.getProperty()));
					break;
				}
			}
		} else {
			criteria.addOrder(Order.desc("createdOn"));
		}
		return new RepositoryPageHelper<Mail>().findPage(criteria, pageable);
	}

}
